<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>推箱子</title>
		<link rel="stylesheet" href="css/test.css">
		<!-- <style>
			html{
				font-size: 10px;
			}
			body{
				background-color: #cacad0;
			}
			.wrap{
				width: 60%;
				height: 620px;
				margin: 50px auto;
				border: 1px solid yellow;
				/* background: url('./img/block.gif'); */
			}
			.wrap .wrap-control{
				display: flex;
				flex-direction: row;
				justify-content: flex-end;
				align-items: center;
			}
			.wrap .wrap-control div{
				width: 80px;
				height: 30px;
				margin-left: 5px;
				border: 2px solid black;
				line-height: 30px;
				text-align: center;
				font-size: 1.5rem;
				border-radius: 10px;
				cursor: pointer;
				user-select: none;
			}
			.wrap .wrap-map{
				position: relative;
				width: 560px;
				height: 560px;
				margin: 10px auto;
				background: url('./img/block.gif');
			}
			.wrap .wrap-map .wall{
				width: 35px;
				height: 46px;
				background: url('img/wall.png')no-repeat;
				position: absolute;
			}
			.wrap .wrap-map #people{
				width: 35px;
				height: 35px;
				/* background: url('img/down.png')no-repeat 0 0 / 35px 35px; */
				position: absolute;
				z-index: 1;
			}
			.wrap .wrap-map .box{
				width: 35px;
				height: 35px;
				background: url('img/box.png')no-repeat 0 0 / 35px 35px;
				position: absolute;
			}
			.wrap .wrap-map .target{
				width: 35px;
				height: 35px;
				background: url('img/ball.png')no-repeat 0 0 / 35px 35px;
				position: absolute;
			}
			.wrap .wrap-map .left{
				background: url('img/left.png')no-repeat 0 0 / 35px 35px;
			}
			.wrap .wrap-map .right{
				background: url('img/right.png')no-repeat 0 0 / 35px 35px;
			}
			.wrap .wrap-map .up{
				background: url('img/up.png')no-repeat 0 0 / 35px 35px;
			}
			.wrap .wrap-map .down{
				background: url('img/down.png')no-repeat 0 0 / 35px 35px;
			}
		</style> -->
	</head>
	<body>
		<div class="wrap">
			<div class="wrap-control">
				<div id="prelevel">上一关</div>
				<div id="nextlevel">下一关</div>
				<div id="prestep">上一步</div>
				<div id="help">大哥救我！</div>
			</div>
			<div class="wrap-map">
			</div>
		</div>
	</body>
	<script type="text/javascript">
		let map = document.querySelectorAll('.wrap-map')[0];
		let hperson = [];
		let hbox = [];
		let mapData = [
			{
				//0是地板，1是墙，2是目标
				map:[
					[0,0,1,1,1,0,0,0],
					[0,0,1,2,1,0,0,0],
					[0,0,1,0,1,1,1,1],
					[1,1,1,0,0,0,2,1],
					[1,2,0,0,0,1,1,1],
					[1,1,1,1,0,1,0,0],
					[0,0,0,1,2,1,0,0],
					[0,0,0,1,1,1,0,0]
				],
				man:{x:4,y:4},
				box:[{x:3,y:3},{x:5,y:3},{x:3,y:4},{x:4,y:5}]
			}
		];

		function Wall(x,y){
			this.x = x;
			this.y = y;
			this.name = document.createElement('div');
			this.name.className = 'wall';
			this.name.setAttribute('style',`top: ${(this.y+3) * 35 - 11}px;left: ${(this.x+3) * 35}px;`);
			map.appendChild(this.name);
		}
		//人物对象构造函数
		function People(x,y){
			this.x = x;
			this.y = y;
			this.left = (x+3) * 35;
			this.top = (y+3) * 35;
			this.name = document.createElement('div');
			this.name.id = "people";
			this.name.className = "down";
			this.name.setAttribute('style',`top: ${this.top}px;left: ${this.left}px;`);
			map.appendChild(this.name);
		}
		People.prototype.move = function(charCode,tag,x,y) {
			//将人物位置存入历史数组

			//移动 设置新位置
			if ( charCode === 37){
				tag.className = "left";
				x -= 35;
				tag.setAttribute("style",`left: ${x}px; top: ${y}px`);
				this.x--;
			}else if ( charCode === 38 ) {
				tag.className = "up";
				y -= 35;
				tag.setAttribute("style",`left: ${x}px; top: ${y}px`);
				this.y--;
			}else if ( charCode === 39 ) {
				tag.className = "right";
				x += 35;
				tag.setAttribute("style",`left: ${x}px; top: ${y}px`);
				this.x++;
			}else if ( charCode === 40 ) {
				tag.className = "down";
				y += 35;
				tag.setAttribute("style",`left: ${x}px; top: ${y}px`);
				this.y++;
			}
			this.left = x;
			this.top = y;
			
		}

		//箱子对象构造函数
		function Box(x,y){
			this.x = x;
			this.y = y;
			this.left = (x+3) * 35;
			this.top = (y+3) * 35;
			this.name = document.createElement('div');
			this.name.className = 'box';
			this.name.setAttribute('style',`top: ${this.top}px;left: ${this.left}px;`);
			map.appendChild(this.name);
		}

		Box.prototype.move = function(charCode,tag,x,y){
			if ( charCode === 37){
				// tag.className = "left";
				x -= 35;
				tag.setAttribute("style",`left: ${x}px; top: ${y}px`);
				this.x--;
			}else if ( charCode === 38 ) {
				// tag.className = "up";
				y -= 35;
				tag.setAttribute("style",`left: ${x}px; top: ${y}px`);
				this.y--;
			}else if ( charCode === 39 ) {
				// tag.className = "right";
				x += 35;
				tag.setAttribute("style",`left: ${x}px; top: ${y}px`);
				this.x++;
			}else if ( charCode === 40 ) {
				// tag.className = "down";
				y += 35;
				tag.setAttribute("style",`left: ${x}px; top: ${y}px`);
				this.y++;
			}
			this.left = x;
			this.top = y;
		}

		//目标对象构造函数
		function Target(x,y){
			this.x = x;
			this.y = y;
			this.name = document.createElement('div');
			this.name.className = 'target';
			this.name.setAttribute('style',`top: ${(this.y+3) * 35}px;left: ${(this.x+3) * 35}px;`);
			map.appendChild(this.name);
		}

		//用于创建一局
		function Game(x) {
			//设置关卡
			this.level = (x-1) || 0;
			//获取地图数据
			this.map = mapData[parseInt(this.level)].map;
			//创建地图
			makeMap(this.map);
			//创建人物对象
			this.manLocals =  mapData[parseInt(this.level)].man;
			this.man = new People(this.manLocals.x,this.manLocals.y);
			//创建箱子对象
			this.boxLocals = mapData[parseInt(this.level)].box;
			this.boxs =  [];
			this.boxLocals.forEach(function(value,index){
				this.boxs[index] = new Box(value.x,value.y);
			},this);
			this.over = false;
		}
		//进行任务判断
		Game.prototype.judge = function(key){
			let manX = this.man.x;
				manY = this.man.y;
			if(key===37){
				//如果按下左方向键，如果人物左边不是墙
				if(this.map[manY][manX-1] != 1){
					//判断左边第一格有没有箱子,如果返回-1，则没有箱子
					let isBox = findBox(this.boxs,(manX-1),manY);
					//不是箱子,只有人物左移一格，更新人物位置
					if(isBox == -1){
						this.man.move(key,this.man.name,this.man.left,this.man.top);
					}
					//如果左一有箱子
					if(isBox != -1){
						//判断左二是不是墙,不是墙则执行
						if(this.map[manY][manX-2] != 1){
							//判断左二是不是箱子
							let isBox_1 = findBox(this.boxs,(manX-2),manY);
							//如果左二不是箱子，则人物和箱子一起向左移一格
							if(isBox_1 == -1){
								
								let boxIndex = isBox.idx;
								
								let boxName = this.boxs[boxIndex].name;
								
								let boxLeft	= this.boxs[boxIndex].left;
								let boxTop	= this.boxs[boxIndex].top;
								this.man.move(key,this.man.name,this.man.left,this.man.top);
								this.boxs[boxIndex].move(key,boxName,boxLeft,boxTop);
							}
						}
					}
				}else {
					this.man.name.className = "left";
				}
			}else if(key === 38){
				if(this.map[manY-1][manX] != 1){
					//判断左边第一格有没有箱子,如果返回-1，则没有箱子
					let isBox = findBox(this.boxs,manX,(manY-1));
					
					//不是箱子,只有人物左移一格，更新人物位置
					if(isBox == -1){
						
						this.man.move(key,this.man.name,this.man.left,this.man.top);
					}
					//如果左一有箱子
					if(isBox != -1){
						
						//判断左二是不是墙,不是墙则执行
						if(this.map[manY-2][manX] != 1){
							//判断左二是不是箱子
							let isBox_1 = findBox(this.boxs,manX,(manY-2));
							
							//如果左二不是箱子，则人物和箱子一起向左移一格
							if(isBox_1 == -1){
								
								let boxIndex = isBox.idx;
								
								let boxName = this.boxs[boxIndex].name;
								
								let boxLeft	= this.boxs[boxIndex].left;
								let boxTop	= this.boxs[boxIndex].top;
								this.man.move(key,this.man.name,this.man.left,this.man.top);
								this.boxs[boxIndex].move(key,boxName,boxLeft,boxTop);
							}
						}
					}
				}else {
					this.man.name.className = "up";
				}
			}else if(key === 39){
				if(this.map[manY][manX+1] != 1){
					//判断左边第一格有没有箱子,如果返回-1，则没有箱子
					let isBox = findBox(this.boxs,(manX+1),manY);
					
					//不是箱子,只有人物左移一格，更新人物位置
					if(isBox == -1){
						
						this.man.move(key,this.man.name,this.man.left,this.man.top);
					}
					//如果左一有箱子
					if(isBox != -1){
						
						//判断左二是不是墙,不是墙则执行
						if(this.map[manY][manX+2] != 1){
							//判断左二是不是箱子
							let isBox_1 = findBox(this.boxs,(manX+2),manY);
							
							//如果左二不是箱子，则人物和箱子一起向左移一格
							if(isBox_1 == -1){
								
								let boxIndex = isBox.idx;
							
								let boxName = this.boxs[boxIndex].name;
								
								let boxLeft	= this.boxs[boxIndex].left;
								let boxTop	= this.boxs[boxIndex].top;
								this.man.move(key,this.man.name,this.man.left,this.man.top);
								this.boxs[boxIndex].move(key,boxName,boxLeft,boxTop);
							}
						}
					}
				}else {
					this.man.name.className = "right";
				}
			}else if(key === 40){
				if(this.map[manY+1][manX] != 1){
					//判断左边第一格有没有箱子,如果返回-1，则没有箱子
					let isBox = findBox(this.boxs,manX,(manY+1));
					
					//不是箱子,只有人物左移一格，更新人物位置
					if(isBox == -1){
						
						this.man.move(key,this.man.name,this.man.left,this.man.top);
					}
					//如果左一有箱子
					if(isBox != -1){
						
						//判断左二是不是墙,不是墙则执行
						if(this.map[manY+2][manX] != 1){
							//判断左二是不是箱子
							let isBox_1 = findBox(this.boxs,manX,(manY+2));
							
							//如果左二不是箱子，则人物和箱子一起向左移一格
							if(isBox_1 == -1){
								
								let boxIndex = isBox.idx;
								
								let boxName = this.boxs[boxIndex].name;
								
								let boxLeft	= this.boxs[boxIndex].left;
								let boxTop	= this.boxs[boxIndex].top;
								this.man.move(key,this.man.name,this.man.left,this.man.top);
								this.boxs[boxIndex].move(key,boxName,boxLeft,boxTop);
							}
						}
					}
				}else {
					this.man.name.className = "down";
				}
			}
		};

		Game.prototype.isPass = function() {
			let arrTarget = [];
			arrLength = 0;
				row = this.map.length;
				column = this.map[0].length;
			for(let i = 0 ; i < row ; i++){
				for(let j = 0 ; j < column ; j++){
					if(this.map[i][j] == 2){
						arrTarget[arrLength] = {x:j,y:i};
						arrLength++;
					}
				}
			}
			//假设已经都重合
			let goon = true;
			// console.log(arrTarget);
			//验证
			arrTarget.forEach((value)=>{
				// console.log(value);
				let bol = findBox(this.boxs,value.x,value.y);
				//如果箱子与目标不重合
				// console.log(bol);
				if(bol == -1) {
					goon = false;
					return;
				}
			});
			if(goon){
				this.over = true;
			}
		}


		//查找特定位置是否有箱子，有则返回箱子，没有则返回-1
		function findBox(boxs,x,y){
			let result = 0;
			    box = {};
				idx = -1;
			boxs.forEach((value,index)=>{
				if(value.x == x && value.y == y){
					result = 1;
					box = value;
					idx = index;
					
				}
				
			})
			
			if(result == 1){
				// console.log(222);
				return {box:box,idx:idx};
			}
			return -1;
		}

		//用于创建画面并返回人物的位置
		function makeMap(data) {
			let row = data.length;
				column = data[0].length;
				manLocal = {
				box:[
					{x:0,y:0},
					{x:0,y:0},
					{x:0,y:0},
					{x:0,y:0}
				]
			};
			let boxNum = 0;
			for(let i = 0 ; i < row ; i++) {
				for(let j = 0 ; j < column ; j++) {
					if(data[i][j] == 1) {
						new Wall(j,i);
					}
					if(data[i][j] == 2) {
						new Target(j,i);
					}
				}
			}
			return manLocal;
		}

		let game = new Game(1);
		// let aPerson = makeMap(first);
		document.onkeydown = function(ev) {
			let key = ev.keyCode;
			game.judge(key);
			game.isPass();
			// console.log()
			if(game.over){
				let delay = setTimeout(()=>{alert("Game Over");},500);
			}
		}
	</script>
	<!-- <script src="js/game.js"></script> -->
</html>
